package com.qdlc.p2p.biz.service.impl;

import com.qd.p2p.adapter.Response;
import com.qd.p2p.adapter.enums.ResponseStatus;
import com.qdlc.p2p.biz.processor.event.CashAwardPayNoticeEvent;
import com.qdlc.p2p.biz.processor.event.RedEnvelopePayNoticeEvent;
import com.qdlc.p2p.biz.processor.event.WineCouponsPayNoticeEvent;
import com.qdlc.p2p.biz.service.AbstractPayService;
import com.qdlc.p2p.biz.service.RPCRequestService;
import com.qdlc.p2p.common.constant.*;
import com.qdlc.p2p.common.core.ReturnResult;
import com.qdlc.p2p.common.core.queue.QueueHandlers;
import com.qdlc.p2p.common.util.BeanCopierUtils;
import com.qdlc.p2p.common.util.DataUtils;
import com.qdlc.p2p.dal.dto.TppTradeLog;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.MessageFormat;
import java.util.Map;

/**
 * Created by hongbinglin on 2016/5/16.
 */
@Service
public class CashAwardPayServiceImpl extends AbstractPayService {

    private static final String CALLBACK_URL = WEB_URL + NotifyUrl.CASH_REWARD_PAY_URL + ".html";

    private final static String BUSINESS_NAME = "投标现金奖励代付-";

    /**
     * 代收交易Log
     */
    private ThreadLocal<TppTradeLog> collectTppTradeLogLocal = new ThreadLocal<TppTradeLog>();

    /**
     * 重新调度
     */
    private ThreadLocal<Integer> autoDispatch = new ThreadLocal<Integer>();

    @Override
    public String getCallBackUrl() {
        return CALLBACK_URL;
    }

    @Override
    public String getBusinessName() {
        return BUSINESS_NAME;
    }

    @Resource
    @Qualifier("bfRPCRequestService")
    private RPCRequestService<Response, TppTradeLog> rpcRequestService;

    @Override
    public TppTradeLog getTppTradeLog() {
        TppTradeLog tppTradeLog = new TppTradeLog();
        BeanCopierUtils.copyProperties(collectTppTradeLogLocal.get(), tppTradeLog);
        tppTradeLog.setId(0l);
        // 非自动调度
        if (autoDispatch.get() != 1) {
            tppTradeLog.setAssociateOrderId(tppTradeLog.getOrderNo());  // 代收订单
            tppTradeLog.setTradeType(TradeCode.C2011.toString());
        }
        tppTradeLog.setAutoDispatch(autoDispatch.get());// 自动调度标识 1:自动,0:非自动
        return tppTradeLog;
    }

    @Override
    public void analyzePars(Object... pars) {
        this.autoDispatch.set(0);// 默认非自动
        if (pars.length != 1 && pars.length != 2) {
            throw new IllegalArgumentException("参数个数正确!");
        }
        try {
            TppTradeLog collectTppTradeLog = (TppTradeLog) pars[0]; // 代收交易Log
            if (collectTppTradeLog == null) {
                throw new IllegalArgumentException("参数类型正确!");
            }
            collectTppTradeLogLocal.set(collectTppTradeLog);
            if (pars.length == 2) {
                this.autoDispatch.set((Integer) pars[1]);// 自动调度标识 1:自动,0:非自动
            }
        } catch (Exception ex) {
            throw new IllegalArgumentException("参数类型正确!");
        }
    }

    @Override
    public void tradeFinish(TppTradeLog tppTradeLog, String depositStatus, double tradeAmount) {

        super.tradeFinishForStatus(tppTradeLog, depositStatus, tradeAmount);
        Map<String, Object> memoMap = DataUtils.getMemo(tppTradeLog.getMemo());
        // 资金变更
        long userId = DataUtils.toLong(memoMap.get("userId")); // 兑换的用户ID

        // 兑现 资金变更
        Global.setTransfer(LogTplNid.LOG_TPL_KEY,  LogTplNid.CASH_AWARD );
        Global.setTransfer("money", tradeAmount);
        accountService.addUseMoneyAndTotal(userId, GeneralAccountType.INVESTOR, tradeAmount);
    }

    @Override
    public void tradeSuccess(TppTradeLog tppTradeLog, String depositStatus) {
        super.tradeSuccessForStatus(tppTradeLog, depositStatus);
    }

    @Override
    public void tradeFail(TppTradeLog tppTradeLog, String depositStatus) {
        super.tradeFailForStatus(tppTradeLog, depositStatus);
        // 回调失败
        requestOrderFail(tppTradeLog);
    }

    @Override
    public ReturnResult requestOrder(TppTradeLog tppTradeLog) {
        Response response = rpcRequestService.wineCouponsPayRequest(tppTradeLog);
        // 未知状态通知 交由消息队列处理
        if (response == null || response.getStatus() == ResponseStatus.UN_KNOW) {
            notice(tppTradeLog, TradeStatus.TRADE_STATUS_UN_KNOW);
            return new ReturnResult(true, "系统处理中!请查看兑现结果!");
        }
        // 代付调用成功
        if (response.getStatus() == ResponseStatus.SUCCESS) {
            tppTradeLog.setRemark(getBusinessName().concat("提交成功"));
            tppTradeService.update(tppTradeLog);
            // 成功通知
            notice(tppTradeLog, TradeStatus.TRADE_STATUS_FINISHED);
            requestOrderSuccess(tppTradeLog); // 请求成功处理
        } else {
            String message = response == null ? "RPC调用失败" : MessageFormat.format("代付失败! resCode:{0} resMessage:{1}",
                    response.getResponseCode(),
                    response.getResponseMsg());
            String responseMessage = response == null ? "RPC调用失败" : response.getResponseMsg();
            logger.info(message);

            // 置为废单
            tppTradeLog.setTradeStatus(TradeStatus.TRADE_STATUS_INVALID.getStatus());
            tppTradeLog.setRemark(getBusinessName().concat("提交失败-" + responseMessage));
            tppTradeService.update(tppTradeLog);
            requestOrderFail(tppTradeLog); // 请求失败处理
            return new ReturnResult(true, message);
        }
        return ReturnResult.SUCCESS;
    }

    /**
     * 发送投标通知 交由队列来执行
     */
    private void notice(TppTradeLog tppTradeLog, TradeStatus tradeStatus) {
        CashAwardPayNoticeEvent event = new CashAwardPayNoticeEvent();
        event.setClientIp(Global.getIP());
        event.setTradeStatus(tradeStatus);
        event.setTppTradeLog(tppTradeLog);
        event.setOutOrderNo(tppTradeLog.getOrderNo());
        event.setDepositAmount(tppTradeLog.getMoney());
        QueueHandlers.put(event);
    }
}
